#pragma once

template <size_t N>
hBitStr& hBitStr::operator>>(std::bitset<N>& s)
{
	s.reset();
	for (size_t i = 0; _beg < _end && i < N; ++i, ++_beg)
	{
		while (dtBitSize <= _beg)
		{
			_beg -= dtBitSize;
			_end -= dtBitSize;
			_data.pop_front();
		}

		_hBitStrDetail::Bit8 bit;
		bit._val  = ((char*)&_data.front())[_beg >> 3];
		s.set(N - i - 1, bit[_beg & 7]);
	}

	return *this;
}

namespace _hBitStrDetail
{
	template <bool IsConst>
	Bit<IsConst>& Bit<IsConst>::operator=(bool b)
	{
		assert(!IsConst);
		assert(_id < 8);

		switch (_id)
		{
		case 0:
			if (b) _owner._uval |= 0x80;
			else _owner._uval &= 0x7f;
		case 1:
			if (b) _owner._uval |= 0x40;
			else _owner._uval &= 0xbf;
		case 2:
			if (b) _owner._uval |= 0x20;
			else _owner._uval &= 0xdf;
		case 3:
			if (b) _owner._uval |= 0x10;
			else _owner._uval &= 0xef;
		case 4:
			if (b) _owner._uval |= 0x8;
			else _owner._uval &= 0xf7;
		case 5:
			if (b) _owner._uval |= 0x4;
			else _owner._uval &= 0xfb;
		case 6:
			if (b) _owner._uval |= 0x2;
			else _owner._uval &= 0xfd;
		case 7:
			if (b) _owner._uval |= 0x1;
			else _owner._uval &= 0xfe;
		default:
			break;
		}

		return *this;
	}

	template <bool IsConst>
	Bit<IsConst>::operator bool() const
	{
		assert(_id < 8);
		switch (_id)
		{
		case 0:
			return _owner._uval & 0x80;
		case 1:
			return _owner._uval & 0x40;
		case 2:
			return _owner._uval & 0x20;
		case 3:
			return _owner._uval & 0x10;
		case 4:
			return _owner._uval & 0x8;
		case 5:
			return _owner._uval & 0x4;
		case 6:
			return _owner._uval & 0x2;
		case 7:
			return _owner._uval & 0x1;
		default:
			break;
		}

		return false;
	}
}